package com.mallcai.bigdata.ladon.service.report.impl.handler.support.rule;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.dpl.vo.DataType;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * @author feixy
 * @version 1.0
 * @date 2019-07-20 19:13
 */
public class RuleOperatorFactory {

    private static final List<IRuleOperator> ALL_LIST = new ArrayList<>();

    private static final LinkedHashMap<String, IRuleOperator> CACHE = new LinkedHashMap(){
        @Override
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return this.size() > 100;
        }
    };

    public static IRuleOperator getRuleOperator(String op, DataType dataType){
        if(StringUtils.isEmpty(op)){
            throw new BusinessException("非法的规则:操作符为空");
        }
        if (dataType == null){
            throw new BusinessException("非法的规则:参数类型为空");
        }

        String opStr = StringUtils.normalizeSpace(op);
        String key = String.format("%s-%s", dataType.getCode(), opStr);
        IRuleOperator ruleOperator = CACHE.computeIfAbsent(key,  k -> select(opStr, dataType));
        if(ruleOperator == null){
            throw  new BusinessException(String.format("非法的规则:参数类型[%s]不支持的操作符[%s]", dataType.getCode(), op));
        }
        return ruleOperator;

    }

    private static IRuleOperator select(String str, DataType dataType) {
        return ALL_LIST.stream()
                .filter(iRuleOperator -> iRuleOperator.support(str, dataType)).findAny()
                .orElse(null);
    }

    static {
        ALL_LIST.add(new EqRuleOperator());
        ALL_LIST.add(new NotEqRuleOperator());
        ALL_LIST.add(new IsNullRuleOperator());
        ALL_LIST.add(new IsNotNullRuleOperator());
        ALL_LIST.add(new BlankRuleOperator());
        ALL_LIST.add(new NotBlankRuleOperator());
        ALL_LIST.add(new StartsWithRuleOperator());
        ALL_LIST.add(new EndsWithRuleOperator());
        ALL_LIST.add(new ContainsRuleOperator());
        ALL_LIST.add(new StringGreatThanOperator());
        ALL_LIST.add(new StringLessThenOperator());
        ALL_LIST.add(new DateGreatThenOperator());
        ALL_LIST.add(new DateLessThenOperator());
        ALL_LIST.add(new NumberGreatThenOperator());
        ALL_LIST.add(new NumberLessThenOperator());
        ALL_LIST.add(new InOperator());
        ALL_LIST.add(new NotInOperator());
        ALL_LIST.add(new IsEmptyRuleOperator());
        ALL_LIST.add(new IsNotEmptyRuleOperator());
    }


}
